package in.ac.dei.edrp.generalLedger.common.dynamiccode;

import java.sql.SQLException;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

public class DynamicCode extends SqlMapClientDaoSupport{
	private String waitFlag = "wait";
	private static int counterUp=0;
	public String generateDynamicCode (DynamicCodeBean dynamicCodeBean, SqlMapClientTemplate sqlMapClientTemplate)throws Exception{
		String finalCode="";
		boolean flag=false;
		String systemValue = "";
		DynamicCodeBean sysOneBean;
		Timer timer;
		sysOneBean = (DynamicCodeBean)sqlMapClientTemplate.queryForObject("dynamicCode.checkvalues",dynamicCodeBean);
		List<DynamicCodeBean>formatList=sqlMapClientTemplate.queryForList("dynamicCode.getRollFormatRecord", dynamicCodeBean);
		if(formatList.size()==0){
			Exception e = new Exception("Code_format_table doesnt have the value for passed codeType");
			throw e;
		}
		int diff=3;	//Default	
		for(int i=0;i<formatList.size();i++){
			if(formatList.get(i).getFormat().equals("SN")){
				int toPosition = Integer.parseInt(formatList.get(i).getToPosition());
				int fromPosition = Integer.parseInt(formatList.get(i).getFromPosition());							
				diff=(toPosition-fromPosition)+1;
			}					
		}
		String tempSeqNo=String.format("%0"+diff+"d", 0);	
		System.out.println("temp sequence no :"+tempSeqNo);
		DynamicCodeBean insertBeanObject = new DynamicCodeBean();
		//no seq no in system table one so new seq no need to create
		if (sysOneBean == null) {
			flag=true;			
			insertBeanObject.setCode(dynamicCodeBean.getCode());
			insertBeanObject.setYear(dynamicCodeBean.getYear());
			insertBeanObject.setSystemValue(tempSeqNo);
			insertBeanObject.setCreatorId(dynamicCodeBean.getCreatorId());
			
			 /* insert a record in system_table_one if no record
			 * exist for the entity
			 */
			sqlMapClientTemplate.insert("dynamicCode.insertsystemvalue",insertBeanObject);
			systemValue=tempSeqNo;
		}
		else if (sysOneBean.getStatusFlag().equalsIgnoreCase("U")) {
			flag=true;
			insertBeanObject.setStatusFlag("L");
			insertBeanObject.setModifierId(dynamicCodeBean.getModifierId());
			insertBeanObject.setCode(dynamicCodeBean.getCode());
			insertBeanObject.setYear(dynamicCodeBean.getYear());
			insertBeanObject.setCreatorId(dynamicCodeBean.getCreatorId());
			/*
			 * if record found then update flag status(from U to L) before
			 * generating Code
			 */
			sqlMapClientTemplate.update("dynamicCode.updateentitysatusflag",insertBeanObject);
			systemValue = String.format("%0"+diff+"d", Integer.parseInt(sysOneBean.getSystemValue()));
			dynamicCodeBean.setSystemValue(systemValue);
			try {
				finalCode = toGenerateCode(dynamicCodeBean, formatList, sqlMapClientTemplate);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			System.out.println("final generated code is :"+finalCode);
//			insertBeanObject.setSystemValue(String.format("%0"+diff+"d", Integer.parseInt(sysOneBean.getSystemValue())));
//			sqlMapClientTemplate.update("dynamicCode.updaterollvalue",insertBeanObject);
			System.out.println("After update value in system table one"+systemValue);
		} else if (sysOneBean.getStatusFlag().equalsIgnoreCase("L")) {
			systemValue = String.format("%0"+diff+"d", Integer.parseInt(sysOneBean.getSystemValue()));
			dynamicCodeBean.setSystemValue(systemValue);
			flag=false;
			//wait since code is unlocked
			int counter=5;		
			while(counter>0){
				waitFlag = chkStatusFlag(dynamicCodeBean,sqlMapClientTemplate);				
                System.out.println("inside recheck !!"+ waitFlag);
                if(waitFlag.equalsIgnoreCase("clear")){
                	break;
                }
                else{
                	counter--;
                }	
                Thread.sleep(10000);
            }
			//after loop run
			if(waitFlag.equalsIgnoreCase("clear")){
				try {
					finalCode = toGenerateCode(dynamicCodeBean, formatList, sqlMapClientTemplate);
				} catch (SQLException e) {
					e.printStackTrace();
				}
				System.out.println("final generated code is :"+finalCode);				
			}
			else{
				System.out.format("Time's up!%n");
                waitFlag="waitUp";
                finalCode="waitup";            
			}              
		}
		return finalCode;
//			timer = new Timer();
//			DynamicCode dynamicCode = new DynamicCode();
//			timer.schedule(dynamicCode.new RemindTask(dynamicCodeBean, sqlMapClientTemplate,timer), 0, 10*1000);
//			System.out.println("after timer attempts : "+waitFlag);
//			flagValue=false;
//		}
		/*dynamicCodeBean.setSystemValue(systemValue);
		if(waitFlag.equalsIgnoreCase("wait")){
			//do nothing just wait
		}
		else{
			if(waitFlag.equalsIgnoreCase("waitup")){
				finalCode="waitup";
				//we need to wait
			}
			else{			
				try {
					finalCode = toGenerateCode(dynamicCodeBean, formatList, sqlMapClientTemplate);
				} catch (SQLException e) {
					e.printStackTrace();
				}
				System.out.println("final generated code is :"+finalCode);
			}
			return finalCode;
		}*/
	}

	/**
	 * method generates the Dynamic code
	 * @param sqlMapClientTemplate 
	 *
	 * @param instance of DynamicCodeBean carrying all the required fields
	 *          
	 * @param List of DynamicCodeBean having all the format for code type
	 *
	 * @throws SQLException
	 */
	private static String toGenerateCode(DynamicCodeBean dynamicCodeBean,List<DynamicCodeBean>formatList, SqlMapClientTemplate sqlMapClientTemplate) throws SQLException {
		
		String formatStr="%0"+dynamicCodeBean.getSystemValue().length()+"d";		
		int value = Integer.parseInt(dynamicCodeBean.getSystemValue()) + 1;
		String seqNo = "";		
		seqNo = String.format(formatStr, value);
		String year = dynamicCodeBean.getYear();
		String month = dynamicCodeBean.getMonth();
		DynamicCodeBean beanObject = new DynamicCodeBean();
		beanObject.setCode(dynamicCodeBean.getCode());
		beanObject.setYear(dynamicCodeBean.getYear());
		beanObject.setSystemValue(seqNo);
		beanObject.setCreatorId(dynamicCodeBean.getCreatorId());
		beanObject.setCreatorId(dynamicCodeBean.getModifierId());
		/*
		 * Query to update code sequence number in system_table_one prior using the
		 * number
		 */
		sqlMapClientTemplate.update("dynamicCode.updaterollvalue", beanObject);
		String dynamicCode="";
		int index=0;
		for(int i=0;i<formatList.size();i++){
			if(Integer.parseInt(formatList.get(i).getFromPosition())==index+1){
				if(formatList.get(i).getFormat().equals("YY")){
					dynamicCode=dynamicCode+year.substring(2);
				}
				else if(formatList.get(i).getFormat().equals("YYYY")){
					dynamicCode=dynamicCode+year;
				}
				else if(formatList.get(i).getFormat().equals("SN")){
					dynamicCode=dynamicCode+seqNo;
				}
//				else if(formatList.get(i).getFormat().equals("ENTCD")){
//					rollNumber=rollNumber+entityCodeObject.getEntityCode();
//				}
				else if(formatList.get(i).getFormat().equals("MM")){
					dynamicCode=dynamicCode+month;
				}
				else{
					dynamicCode=dynamicCode+formatList.get(i).getFormat();
				}
				index=Integer.parseInt(formatList.get(i).getToPosition());
			}
		}		
		return dynamicCode;		
	}

	public static String updateStatuFlag(DynamicCodeBean dynamicCodeBean, SqlMapClientTemplate sqlMapClientTemplate)throws Exception{
		String status = "false";
		dynamicCodeBean.setStatusFlag("U");
		int updateResult = sqlMapClientTemplate.update("dynamicCode.updateentitysatusflag",dynamicCodeBean);
		System.out.println("int result aftyer statusflag update: "+updateResult);
		if(updateResult>0){
			status = "true";
		}
		else{
			throw new Exception() ;
		}
		return status;
	}
	
	class RemindTask extends TimerTask {
//		String waitFlag = "wait";
        int numOfAttempt = 5;
        DynamicCodeBean dynamicCodeBean;
        SqlMapClientTemplate sqlMapClientTemplate;
        Timer timer;
        RemindTask(DynamicCodeBean dynamicCodeBean, SqlMapClientTemplate sqlMapClientTemplate, Timer timer){
        	this.dynamicCodeBean=dynamicCodeBean;
        	this.sqlMapClientTemplate = sqlMapClientTemplate;
        	this.timer = timer;
        	System.out.println("in timer constructor system value :"+dynamicCodeBean.getSystemValue());
        }
        
        public void run() {
        	try {
	            if (numOfAttempt > 0) {            	
	            	waitFlag = chkStatusFlag(dynamicCodeBean,sqlMapClientTemplate);				
	                System.out.println("inside recheck !!"+ waitFlag);
	                if(waitFlag.equalsIgnoreCase("clear")){
	                	timer.cancel();
	                }
	                else{
	                	numOfAttempt--;
	                }	                
	            } else {
	                System.out.format("Time's up!%n");
	                waitFlag="waitUp";
	                timer.cancel(); //Not necessary because
	                                  //we call System.exit
	//                System.exit(0);   //Stops the AWT thread 
	                                  //(and everything else)
	            }
        	} catch (Exception e) {			
				e.printStackTrace();
			}
        }
    }
	
	private String chkStatusFlag(DynamicCodeBean dynamicCodeBean, SqlMapClientTemplate sqlMapClientTemplate){
		counterUp = counterUp+1;
		System.out.println("counter up :"+counterUp);
//		String waitFlag = "wait";
		DynamicCodeBean sysOneBean;
		sysOneBean = (DynamicCodeBean)sqlMapClientTemplate.queryForObject("dynamicCode.checkvalues",dynamicCodeBean);
		DynamicCodeBean insertBeanObject = new DynamicCodeBean();
		insertBeanObject.setCode(dynamicCodeBean.getCode());
		insertBeanObject.setYear(dynamicCodeBean.getYear());
//		insertBeanObject.setSystemValue(tempSeqNo);
		insertBeanObject.setCreatorId(dynamicCodeBean.getCreatorId());
		if (sysOneBean == null) {
			waitFlag = "clear";
			System.out.println("there is some prblm check the system table one: ");
		}
		else if (sysOneBean.getStatusFlag().equalsIgnoreCase("U")) {
			insertBeanObject.setStatusFlag("L");
			insertBeanObject.setModifierId(dynamicCodeBean.getModifierId());
			/*
			 * if record found then update flag status(from U to L) before
			 * generating Code
			 */
			sqlMapClientTemplate.update("dynamicCode.updateentitysatusflag",insertBeanObject);
			waitFlag = "clear";
		}
		else if (sysOneBean.getStatusFlag().equalsIgnoreCase("L")) {
			/*if(counterUp==2){
				insertBeanObject.setStatusFlag("U");
				insertBeanObject.setModifierId(dynamicCodeBean.getModifierId());
				
				 * if record found then update flag status(from U to L) before
				 * generating Code
				 
				sqlMapClientTemplate.update("dynamicCode.updateentitysatusflag",insertBeanObject);
			}*/
			waitFlag = "wait";
		}
		return waitFlag;
	}
}
